﻿/*----------------------------------------------------------------
// 公司名称：公司名称
// 
// 产品名称：Gaf
//
// 创 建 人：netcasewqs
// 创建日期：2022/3/4
// 邮    箱：netcasewqs@qq.com
//
// Copyright (C) 2022 Gaf，保留所有权利。
//
//----------------------------------------------------------------*/

using Microsoft.Extensions.Hosting;

namespace Gaf;

/// <summary>
/// 
/// </summary>
public static class GafExtensions
{
    /// <summary>
    /// 创建Gaf框架
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="action"></param>
    /// <param name="options"></param>
    /// <returns></returns>
    public static IHostBuilder CreateGaf(this IHostBuilder builder, Action<IGaf>? action = null, GafOptions? options = null)
    {
        var gaf = GafManager.Create(options);
        action?.Invoke(gaf);

        return builder;
    }

    /// <summary>
    /// 配置Gaf 框架
    /// </summary>
    /// <param name="builder"></param>
    /// <param name="configuration"></param>
    /// <returns></returns>
    public static IHostBuilder ConfigureGaf(this IHostBuilder builder, IConfiguration? configuration = null)
    {
        builder.ConfigureServices((ctx, servers) =>
        {
            GafManager.Current.Configure(servers, PopulateConfiguration(servers, configuration));
        });

        return builder;
    }

    /// <summary>
    /// 创建并配置Gaf 框架
    /// </summary>
    public static void AddGaf(this IServiceCollection services, IConfiguration? configuration = null, Action<IGaf>? action = null, GafOptions? options = null)
    {
        if (services == null) throw new ArgumentNullException(nameof(services));

        configuration = PopulateConfiguration(services, configuration);

        var gaf = GafManager.Create(options);
        action?.Invoke(gaf);
        gaf.Configure(services, configuration);
    }

    private static IConfiguration PopulateConfiguration(IServiceCollection services, IConfiguration? configuration)
    {
        if (configuration == null)
        {
            var service = services.FirstOrDefault(p => p.ServiceType == typeof(IConfiguration)) ?? throw new ArgumentNullException(nameof(configuration));
            if (service.ImplementationFactory != null)
            {
                var o = service.ImplementationFactory((IServiceProvider)null!);
                configuration = (IConfiguration)o;
            }

            if (configuration == null) throw new ArgumentNullException(nameof(configuration));
        }

        return configuration;
    }

    /// <summary>
    /// 启动Gaf
    /// </summary>
    public static void UseGaf(this IServiceProvider provider)
    {
        if (provider == null) throw new ArgumentNullException(nameof(provider));
        var gaf = provider.GetService<IGaf>();
        if (gaf == null) throw new ArgumentNullException(nameof(gaf));
        gaf.Start(provider);
    }

}